<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .scroll_box {
            width: 300px;
            height: 400px;
            border: 1px solid #000;
            overflow: auto;
        }

        .item {
            padding: 10px;
            line-height: 20px;
            font-size: 16px;
        }
    </style>
</head>

<body>

    <h2>虚拟列表</h2>
    <!-- 固定高度 -->
    <div class="scroll_box">
        <!-- 滚动盒子 -->
        <div class="scroll_content">
            <!-- 偏移盒子 -->
            <div class="scroll_item"></div>
        </div>

    </div>

    <script>
        /**
         * 固定item高度的实现
         * 思路：
         * 1.明确三个盒子，一个固定盒子，一个滚动盒子，一个偏移盒子
         * 2. 固定盒子高度固定，滚动盒子高度根据内容高度自适应，偏移盒子偏移由滚动距离决定
         * 3. 监听滚动事件，根据滚动距离计算需要渲染的起始和结束位置，然后渲染对应的数据，和设置偏移量
         * 
         * **/

        let scroll_box = document.querySelector('.scroll_box');
        let scroll_content = document.querySelector('.scroll_content');
        let scroll_item = document.querySelector('.scroll_item');

        let scroll_box_height = 400; // 固定盒子高度

        let total = 100000

        // 设置滚动内容的高度，根据总条数和每条高度计算
        scroll_content.style.height = total * 40 + 'px';

        render(0)
        // 监听滚动
        scroll_box.addEventListener('scroll', function () {
            render(scroll_box.scrollTop)
        })

        function render(scrollTop) {
            // 计算当前需要渲染的起始和结束位置，向下取整
            let start = Math.floor(scrollTop / 40);
            // let end = Math.min(start + 15, total);
            let end = Math.ceil(Math.min((scrollTop + scroll_box_height) / 40, total));
            let html = '';
            for (let i = start; i < end; i++) { html += `<div class="item">第${i}条</div>` }
            scroll_item.innerHTML = html; // 设置偏移盒子内容
            scroll_item.style.transform = `translateY(${start * 40}px)`; // 设置偏移盒子位置
        }




    </script>
</body>

</html>